<!doctype html>














<!-- `site.alt_lang` can specify a language different from the UI -->
<html lang="en" 
  
>
  <!-- The Head -->

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <meta name="theme-color" media="(prefers-color-scheme: light)" content="#f7f7f7">
  <meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1b1b1e">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
  <meta
    name="viewport"
    content="width=device-width, user-scalable=no initial-scale=1, shrink-to-fit=no, viewport-fit=cover"
  >

  

  

  
    <!-- Begin Jekyll SEO tag v2.8.0 -->
<meta name="generator" content="Jekyll v4.3.2" />
<meta property="og:title" content="linux Slab" />
<meta name="author" content="Chunsheng Luo" />
<meta property="og:locale" content="en" />
<meta name="description" content="一、slab" />
<meta property="og:description" content="一、slab" />
<link rel="canonical" href="https://luochenglcs.github.io/posts/linux-slab/" />
<meta property="og:url" content="https://luochenglcs.github.io/posts/linux-slab/" />
<meta property="og:site_name" content="Cheng Luo" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2022-12-08T00:00:00+00:00" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:title" content="linux Slab" />
<meta name="twitter:site" content="@luochenglcs" />
<meta name="twitter:creator" content="@Chunsheng Luo" />
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"Chunsheng Luo","url":"https://github.com/luochenglcs"},"dateModified":"2023-08-07T07:02:12+00:00","datePublished":"2022-12-08T00:00:00+00:00","description":"一、slab","headline":"linux Slab","mainEntityOfPage":{"@type":"WebPage","@id":"https://luochenglcs.github.io/posts/linux-slab/"},"url":"https://luochenglcs.github.io/posts/linux-slab/"}</script>
<!-- End Jekyll SEO tag -->

  

  <title>linux Slab | Cheng Luo
  </title>

  <!--
  The Favicons for Web, Android, Microsoft, and iOS (iPhone and iPad) Apps
  Generated by: https://realfavicongenerator.net/
-->



<link rel="apple-touch-icon" sizes="180x180" href="/assets/img/favicons/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/assets/img/favicons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/img/favicons/favicon-16x16.png">
<link rel="manifest" href="/assets/img/favicons/site.webmanifest">
<link rel="shortcut icon" href="/assets/img/favicons/favicon.ico">
<meta name="apple-mobile-web-app-title" content="Cheng Luo">
<meta name="application-name" content="Cheng Luo">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="msapplication-config" content="/assets/img/favicons/browserconfig.xml">
<meta name="theme-color" content="#ffffff">


  
    
      <link rel="preconnect" href="https://fonts.googleapis.com" >
      <link rel="dns-prefetch" href="https://fonts.googleapis.com" >
    
      <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
      <link rel="dns-prefetch" href="https://fonts.gstatic.com" crossorigin>
    
      <link rel="preconnect" href="https://fonts.googleapis.com" >
      <link rel="dns-prefetch" href="https://fonts.googleapis.com" >
    
      <link rel="preconnect" href="https://cdn.jsdelivr.net" >
      <link rel="dns-prefetch" href="https://cdn.jsdelivr.net" >
    

    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Lato&family=Source+Sans+Pro:wght@400;600;700;900&display=swap">
  

  <!-- GA -->
  

  <!-- Bootstrap -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css">

  <!-- Font Awesome -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.0/css/all.min.css">

  <link rel="stylesheet" href="/assets/css/style.css">

  
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tocbot@4.21.0/dist/tocbot.min.css">
  

  
    <!-- Manific Popup -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/magnific-popup@1.1.0/dist/magnific-popup.min.css">
  

  <!-- JavaScript -->

  
    <!-- Switch the mode between dark and light. -->

<script type="text/javascript">
  class ModeToggle {
    static get MODE_KEY() {
      return 'mode';
    }
    static get MODE_ATTR() {
      return 'data-mode';
    }
    static get DARK_MODE() {
      return 'dark';
    }
    static get LIGHT_MODE() {
      return 'light';
    }
    static get ID() {
      return 'mode-toggle';
    }

    constructor() {
      if (this.hasMode) {
        if (this.isDarkMode) {
          if (!this.isSysDarkPrefer) {
            this.setDark();
          }
        } else {
          if (this.isSysDarkPrefer) {
            this.setLight();
          }
        }
      }

      let self = this;

      /* always follow the system prefers */
      this.sysDarkPrefers.addEventListener('change', () => {
        if (self.hasMode) {
          if (self.isDarkMode) {
            if (!self.isSysDarkPrefer) {
              self.setDark();
            }
          } else {
            if (self.isSysDarkPrefer) {
              self.setLight();
            }
          }

          self.clearMode();
        }

        self.notify();
      });
    } /* constructor() */

    get sysDarkPrefers() {
      return window.matchMedia('(prefers-color-scheme: dark)');
    }

    get isSysDarkPrefer() {
      return this.sysDarkPrefers.matches;
    }

    get isDarkMode() {
      return this.mode === ModeToggle.DARK_MODE;
    }

    get isLightMode() {
      return this.mode === ModeToggle.LIGHT_MODE;
    }

    get hasMode() {
      return this.mode != null;
    }

    get mode() {
      return sessionStorage.getItem(ModeToggle.MODE_KEY);
    }

    /* get the current mode on screen */
    get modeStatus() {
      if (this.isDarkMode || (!this.hasMode && this.isSysDarkPrefer)) {
        return ModeToggle.DARK_MODE;
      } else {
        return ModeToggle.LIGHT_MODE;
      }
    }

    setDark() {
      document.documentElement.setAttribute(ModeToggle.MODE_ATTR, ModeToggle.DARK_MODE);
      sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.DARK_MODE);
    }

    setLight() {
      document.documentElement.setAttribute(ModeToggle.MODE_ATTR, ModeToggle.LIGHT_MODE);
      sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.LIGHT_MODE);
    }

    clearMode() {
      document.documentElement.removeAttribute(ModeToggle.MODE_ATTR);
      sessionStorage.removeItem(ModeToggle.MODE_KEY);
    }

    /* Notify another plugins that the theme mode has changed */
    notify() {
      window.postMessage(
        {
          direction: ModeToggle.ID,
          message: this.modeStatus
        },
        '*'
      );
    }

    flipMode() {
      if (this.hasMode) {
        if (this.isSysDarkPrefer) {
          if (this.isLightMode) {
            this.clearMode();
          } else {
            this.setLight();
          }
        } else {
          if (this.isDarkMode) {
            this.clearMode();
          } else {
            this.setDark();
          }
        }
      } else {
        if (this.isSysDarkPrefer) {
          this.setLight();
        } else {
          this.setDark();
        }
      }

      this.notify();
    } /* flipMode() */
  } /* ModeToggle */

  const modeToggle = new ModeToggle();
</script>

  

  <!-- A placeholder to allow defining custom metadata -->

</head>


  <body>
    <!-- The Side Bar -->

<div id="sidebar" class="d-flex flex-column align-items-end">
  <div class="profile-wrapper">
    <a href="/" id="avatar" class="rounded-circle">
      
        
        <img src="/assets/img/favicons/android-chrome-512x512.png" width="112" height="112" alt="avatar" onerror="this.style.display='none'">
      
    </a>

    <div class="site-title">
      <a href="/">Cheng Luo</a>
    </div>
    <div class="site-subtitle fst-italic">Linux operating system engineer</div>
  </div>
  <!-- .profile-wrapper -->

  <ul class="nav flex-column flex-grow-1 w-100 ps-0">
    <!-- home -->
    <li class="nav-item">
      <a href="/" class="nav-link">
        <i class="fa-fw fas fa-home"></i>
        <span>HOME</span>
      </a>
    </li>
    <!-- the real tabs -->
    
      <li class="nav-item">
        <a href="/categories/" class="nav-link">
          <i class="fa-fw fas fa-stream"></i>
          

          <span>CATEGORIES</span>
        </a>
      </li>
      <!-- .nav-item -->
    
      <li class="nav-item">
        <a href="/tags/" class="nav-link">
          <i class="fa-fw fas fa-tags"></i>
          

          <span>TAGS</span>
        </a>
      </li>
      <!-- .nav-item -->
    
      <li class="nav-item">
        <a href="/archives/" class="nav-link">
          <i class="fa-fw fas fa-archive"></i>
          

          <span>ARCHIVES</span>
        </a>
      </li>
      <!-- .nav-item -->
    
      <li class="nav-item">
        <a href="/about/" class="nav-link">
          <i class="fa-fw fas fa-info-circle"></i>
          

          <span>ABOUT</span>
        </a>
      </li>
      <!-- .nav-item -->
    
  </ul>
  <!-- ul.nav.flex-column -->

  <div class="sidebar-bottom d-flex flex-wrap  align-items-center w-100">
    
      <button class="mode-toggle btn" aria-label="Switch Mode">
        <i class="fas fa-adjust"></i>
      </button>

      
        <span class="icon-border"></span>
      
    

    
      

      
        <a
          href="https://github.com/luochenglcs"
          aria-label="github"
          

          
            target="_blank"
            
          

          

          
            rel="noopener noreferrer"
          
        >
          <i class="fab fa-github"></i>
        </a>
      
    
      

      
    
      

      
        <a
          href="javascript:location.href = 'mailto:' + ['luochunsheng','ustc.edu'].join('@')"
          aria-label="email"
          

          

          

          
        >
          <i class="fas fa-envelope"></i>
        </a>
      
    
  </div>
  <!-- .sidebar-bottom -->
</div>
<!-- #sidebar -->


    <div id="main-wrapper" class="d-flex justify-content-center">
      <div id="main" class="container px-xxl-5">
        <!-- The Top Bar -->

<div id="topbar-wrapper">
  <div
    id="topbar"
    class="container d-flex align-items-center justify-content-between h-100"
  >
    <span id="breadcrumb">
      

      
        
          
            <span>
              <a href="/">
                Home
              </a>
            </span>

          
        
          
        
          
            
              <span>linux Slab</span>
            

          
        
      
    </span>
    <!-- endof #breadcrumb -->

    <i id="sidebar-trigger" class="fas fa-bars fa-fw"></i>

    <div id="topbar-title">
      Post
    </div>

    <i id="search-trigger" class="fas fa-search fa-fw"></i>
    <span id="search-wrapper" class="align-items-center">
      <i class="fas fa-search fa-fw"></i>
      <input
        class="form-control"
        id="search-input"
        type="search"
        aria-label="search"
        autocomplete="off"
        placeholder="Search..."
      >
    </span>
    <span id="search-cancel">Cancel</span>
  </div>
</div>

        











<div class="row">
  <!-- core -->
  <div id="core-wrapper" class="col-12 col-lg-11 col-xl-9 pe-xl-4">
    

    <div class="post px-1 px-md-2">
      

      
        
      
        <!-- Refactor the HTML structure -->



<!--
  In order to allow a wide table to scroll horizontally,
  we suround the markdown table with `<div class="table-wrapper">` and `</div>`
-->



<!--
  Fixed kramdown code highlight rendering:
  https://github.com/penibelst/jekyll-compress-html/issues/101
  https://github.com/penibelst/jekyll-compress-html/issues/71#issuecomment-188144901
-->



<!-- Change the icon of checkbox -->


<!-- images -->



  
  

  <!-- CDN URL -->
  

  <!-- Add image path -->
  

  
    
      
      
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  
    

    
    

    

    
    

    
    
    
    

    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    
      

      
      
      

      
    

    <!-- take out classes -->
    

    

    

    

    <!-- lazy-load images <https://github.com/aFarkas/lazysizes#readme> -->
    
    

    <!-- add image placeholder -->
    
      
    

    <!-- Bypass the HTML-proofer test -->
    

    
      <!-- make sure the `<img>` is wrapped by `<a>` -->
      

      
        <!-- create the image wrapper -->
        
      
    

    <!-- combine -->
    

  

  



<!-- Add header for code snippets -->



<!-- Create heading anchors -->





  
  

  

  
  

  
    
    

    
      
        
        
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    

    

  

  
  

  
    
    

    
      
        
        
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    

    

  

  
  

  
    
    

    
      
        
        
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    
      

      
      

      
      
      

      

    

    

  




<!-- return -->




<h1 data-toc-skip>linux Slab</h1>

<div class="post-meta text-muted">
    <!-- published date -->
    <span>
      Posted
      <!--
  Date format snippet
  See: ${JS_ROOT}/utils/locale-dateime.js
-->





<em
  class=""
  data-ts="1670457600"
  data-df="ll"
  
    data-bs-toggle="tooltip" data-bs-placement="bottom"
  
>
  Dec  8, 2022
</em>

    </span>

    <!-- lastmod date -->
    
    <span>
      Updated
      <!--
  Date format snippet
  See: ${JS_ROOT}/utils/locale-dateime.js
-->





<em
  class=""
  data-ts="1691391732"
  data-df="ll"
  
    data-bs-toggle="tooltip" data-bs-placement="bottom"
  
>
  Aug  7, 2023
</em>

    </span>
    

  

  <div class="d-flex justify-content-between">
    <!-- author(s) -->
    <span>
      

      By

      <em>
      
        
          <a href="https://github.com/luochenglcs">Chunsheng Luo</a>
          
        
      
      </em>
    </span>

    <div>
      <!-- read time -->
      <!-- Calculate the post's reading time, and display the word count in tooltip -->



<!-- words per minute -->










<!-- return element -->
<span
  class="readtime"
  data-bs-toggle="tooltip"
  data-bs-placement="bottom"
  title="2818 words"
>
  <em>15 min</em> read</span>

    </div>

  </div> <!-- .d-flex -->

</div> <!-- .post-meta -->
<div class="post-content">
  <h3 id="一slab"><span class="me-2">一、slab</span><a href="#一slab" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h3>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
</pre></td><td class="rouge-code"><pre><span class="nl">https:</span><span class="c1">//zhuanlan.zhihu.com/p/166649492 Linux内存管理：slub分配器</span>
<span class="n">https</span><span class="o">:</span><span class="c1">//www.jianshu.com/p/95d68389fbd1 slab分配器</span>
<span class="err">细节拉满，</span><span class="mi">80</span> <span class="err">张图带你一步一步推演</span> <span class="n">slab</span> <span class="err">内存池的设计与实现</span>
<span class="n">https</span><span class="o">:</span><span class="c1">//segmentfault.com/a/1190000043626203  </span>
</pre></td></tr></tbody></table></code></div></div>

<p>​	内核中的物理内存由伙伴系统(buddy system)进行管理，它的分配粒度是以物理页帧(page)为单位的，但内核中有大量的数据结构只需要若干bytes的空间，倘若仍按页来分配，势必会造成大量的内存被浪费掉。slab分配器的出现就是为了解决内核中这些小块内存分配与管理的难题。slab分配器是基于buddy页分配器，在它上面实现了一层面向对象的缓存管理机制。</p>

<p><a href="/posts/.\images\linux-slab\slab_kmem_cache_create_from_buddy_system.jpg" class="popup img-link "><img data-src="/posts/.\images\linux-slab\slab_kmem_cache_create_from_buddy_system.jpg" div="" align="left" style="zoom:50%" class="lazyload" data-proofer-ignore></a></p>

<p><a href="/posts/.\images\linux-slab\slab_compound_page.png" class="popup img-link "><img data-src="/posts/.\images\linux-slab\slab_compound_page.png" div="" align="left" style="zoom:100%" class="lazyload" data-proofer-ignore></a></p>

<h4 id="1-主要数据结构"><span class="me-2">1) 主要数据结构</span><a href="#1-主要数据结构" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h4>

<h5 id="1-struct-kmem_cache"><span class="me-2">1 struct kmem_cache</span><a href="#1-struct-kmem_cache" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h5>

<p><a href="/posts/.\images\linux-slab\slab_struct_kmem_cache.jpg" class="popup img-link "><img data-src="/posts/.\images\linux-slab\slab_struct_kmem_cache.jpg" div="" align="left" style="zoom:80%" class="lazyload" data-proofer-ignore></a></p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
</pre></td><td class="rouge-code"><pre><span class="k">struct</span> <span class="n">kmem_cache</span> <span class="p">{</span>
  	  <span class="cm">/*per-cpu变量，用来实现每个CPU上的slab缓存。好处如下：
        1.促使cpu_slab-&gt;freelist可以无锁访问，避免了竞争，提升分配速度
        2.使得本地cpu缓存中分配出的objects被同一cpu访问，提升TLB对object的命中率
        (因为一个page中有多个object，他们共用同一个PTE)
        */</span>
        <span class="k">struct</span> <span class="n">kmem_cache_cpu</span> <span class="n">__percpu</span> <span class="o">*</span><span class="n">cpu_slab</span><span class="p">;</span>
        <span class="n">slab_flags_t</span> <span class="n">flags</span><span class="p">;</span>        <span class="cm">/* 下面这些是初始化kmem_cache时会设置的一些变量
         分配时会用到的flags */</span>
        <span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">min_partial</span><span class="p">;</span><span class="cm">/*kmem_cache_shrink缩减partial slabs时，
        将被保有slab的最小值。set_min_partial(s, ilog2(s-&gt;size)/2)设置。*/</span>
        <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">size</span><span class="p">;</span> <span class="cm">/*object的实际大小，包含元数据和对齐的空间*/</span>
        <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">object_size</span><span class="p">;</span>	<span class="cm">/*object中payload的大小，即目标数据结构的实际大小*/</span>
        <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">offset</span><span class="p">;</span><span class="cm">/*每个free object中都存了next free object的地址，但是并未
        存储在object的首地址，而是首地址加上offset的地方*/</span>
        <span class="k">struct</span> <span class="n">kmem_cache_order_objects</span> <span class="n">oo</span><span class="p">;</span> <span class="cm">/*此结构体实际是个unsigned int,
         page_order &lt;&lt; 16 || slab_object_num &amp; 0xFFFF */</span>
        <span class="cm">/* Allocation and freeing of slabs */</span>
        <span class="k">struct</span> <span class="n">kmem_cache_order_objects</span> <span class="n">max</span><span class="p">;</span>
        <span class="k">struct</span> <span class="n">kmem_cache_order_objects</span> <span class="n">min</span><span class="p">;</span>
        <span class="n">gfp_t</span> <span class="n">allocflags</span><span class="p">;</span>       <span class="cm">/* gfp flags to use on each alloc 标准gfp掩码，
        用于从buddy分配页面时 */</span>
        <span class="kt">int</span> <span class="n">refcount</span><span class="p">;</span>           <span class="cm">/* Refcount for slab cache destroy */</span>
        <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">ctor</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="p">);</span> 	<span class="cm">/*object的构造函数，通常不使用*/</span>
        <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">inuse</span><span class="p">;</span>    	<span class="cm">/*object中到metadata的偏移*/</span>
        <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">align</span><span class="p">;</span>    	<span class="cm">/*对齐大小。澄清：slab中对齐方式通常有两种。
        1是按处理器字长对齐;2是按照cacheline大小对齐。*/</span>
        <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">red_left_pad</span><span class="p">;</span>      <span class="cm">/* Left redzone padding size
         若flags中使用REDZONE时有意义*/</span>
    	<span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">name</span><span class="p">;</span><span class="cm">/*对象名称，例：mm_struct task_struct*/</span>
    	<span class="k">struct</span> <span class="n">list_head</span> <span class="n">list</span><span class="p">;</span> 	<span class="cm">/*kmem_cache的链表结构，通过此成员串在slab_caches链表上*/</span>
		<span class="cm">/*下面两个成员用于表示对象内部的一块空间，使userspace可以访问其中的内容。具体可以看kmem_cache_create_usercopy的实现*/</span>
        <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">useroffset</span><span class="p">;</span>   <span class="cm">/* 类似offsetof(struct ext4_inode_info, i_data), ext4_inode_info-&gt;i_data用户态可访问 */</span>
        <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">usersize</span><span class="p">;</span>    <span class="cm">/* sizeof_field(struct ext4_inode_info, i_data) */</span>
        <span class="k">struct</span> <span class="n">kmem_cache_node</span> <span class="o">*</span><span class="n">node</span><span class="p">[</span><span class="n">MAX_NUMNODES</span><span class="p">];</span>	<span class="cm">/*每个node对应一个数组项，kmem_cache_node中包含partial slab链表*/</span>
<span class="p">};</span>
<span class="k">struct</span> <span class="n">kmem_cache_cpu</span> <span class="p">{</span>
        <span class="kt">void</span> <span class="o">**</span><span class="n">freelist</span><span class="p">;</span>      <span class="cm">/*指向下面page指向的slab中的第一个free object*/</span>
    	<span class="cm">/* Globally unique transaction id */</span>
        <span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">tid</span><span class="p">;</span>      
        <span class="k">struct</span> <span class="n">page</span> <span class="o">*</span><span class="n">page</span><span class="p">;</span> <span class="cm">/*指向当前正在使用的slab*/</span>     
        <span class="k">struct</span> <span class="n">page</span> <span class="o">*</span><span class="n">partial</span><span class="p">;</span> <span class="cm">/*本地slab缓存池中的partial slab链表*/</span>
<span class="p">};</span>

<span class="k">struct</span> <span class="n">kmem_cache_node</span> <span class="p">{</span>
        <span class="n">spinlock_t</span> <span class="n">list_lock</span><span class="p">;</span>   	<span class="cm">/*kmem_cache_node数据结构的自选锁，可能涉及到多核访问*/</span>
        <span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">nr_partial</span><span class="p">;</span>    	<span class="cm">/*node中slab的数量*/</span>
        <span class="k">struct</span> <span class="n">list_head</span> <span class="n">partial</span><span class="p">;</span>    	<span class="cm">/*指向partial slab链表*/</span>
<span class="p">};</span>
</pre></td></tr></tbody></table></code></div></div>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
</pre></td><td class="rouge-code"><pre><span class="n">crash</span><span class="o">&gt;</span> <span class="k">struct</span> <span class="n">kmem_cache</span> <span class="o">-</span><span class="n">x</span> <span class="n">ffff8001f8e80800</span>
<span class="k">struct</span> <span class="n">kmem_cache</span> <span class="p">{</span>
  <span class="n">cpu_slab</span> <span class="o">=</span> <span class="mh">0xfffefdfe40f4d3d0</span><span class="p">,</span> 
  <span class="n">flags</span> <span class="o">=</span> <span class="mh">0x40002000</span><span class="p">,</span> 
  <span class="n">min_partial</span> <span class="o">=</span> <span class="mh">0x5</span><span class="p">,</span> 
  <span class="n">size</span> <span class="o">=</span> <span class="mh">0x680</span><span class="p">,</span> 
  <span class="n">object_size</span> <span class="o">=</span> <span class="mh">0x640</span><span class="p">,</span> 
  <span class="n">offset</span> <span class="o">=</span> <span class="mh">0x640</span><span class="p">,</span> 
  <span class="n">cpu_partial</span> <span class="o">=</span> <span class="mh">0x6</span><span class="p">,</span> 
  <span class="n">oo</span> <span class="o">=</span> <span class="p">{</span>
    <span class="n">x</span> <span class="o">=</span> <span class="mh">0x30013</span>
  <span class="p">},</span> 
  <span class="n">max</span> <span class="o">=</span> <span class="p">{</span>
    <span class="n">x</span> <span class="o">=</span> <span class="mh">0x30013</span>
  <span class="p">},</span> 
  <span class="n">min</span> <span class="o">=</span> <span class="p">{</span>
    <span class="n">x</span> <span class="o">=</span> <span class="mh">0x2</span>
  <span class="p">},</span> 
  <span class="n">allocflags</span> <span class="o">=</span> <span class="mh">0x4000</span><span class="p">,</span> 
  <span class="n">refcount</span> <span class="o">=</span> <span class="mh">0x1</span><span class="p">,</span> 
  <span class="n">ctor</span> <span class="o">=</span> <span class="mh">0xffff000000aba000</span><span class="p">,</span> 
  <span class="n">inuse</span> <span class="o">=</span> <span class="mh">0x640</span><span class="p">,</span> 
  <span class="n">align</span> <span class="o">=</span> <span class="mh">0x40</span><span class="p">,</span> 
  <span class="n">red_left_pad</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
  <span class="n">name</span> <span class="o">=</span> <span class="mh">0xffff8001facd7d00</span> <span class="s">"slab_test_cachep"</span><span class="p">,</span> 
  <span class="n">list</span> <span class="o">=</span> <span class="p">{</span>
    <span class="n">next</span> <span class="o">=</span> <span class="mh">0xffff8000fee71260</span><span class="p">,</span> 
    <span class="n">prev</span> <span class="o">=</span> <span class="mh">0xffff000081308bb0</span> <span class="o">&lt;</span><span class="n">slab_caches</span><span class="o">&gt;</span>
  <span class="p">},</span> 
  <span class="n">kobj</span> <span class="o">=</span> <span class="p">{</span>
    <span class="n">name</span> <span class="o">=</span> <span class="mh">0xffff8001facd7c00</span> <span class="s">"slab_test_cachep"</span><span class="p">,</span> 
    <span class="n">entry</span> <span class="o">=</span> <span class="p">{</span>
      <span class="n">next</span> <span class="o">=</span> <span class="mh">0xffff8000fc8ba800</span><span class="p">,</span> 
      <span class="n">prev</span> <span class="o">=</span> <span class="mh">0xffff8000fee71278</span>
    <span class="p">},</span> 
    <span class="n">parent</span> <span class="o">=</span> <span class="mh">0xffff8000fc8ba818</span><span class="p">,</span> 
    <span class="n">kset</span> <span class="o">=</span> <span class="mh">0xffff8000fc8ba800</span><span class="p">,</span> 
    <span class="n">ktype</span> <span class="o">=</span> <span class="mh">0xffff000081311898</span> <span class="o">&lt;</span><span class="n">slab_ktype</span><span class="o">&gt;</span><span class="p">,</span> 
    <span class="n">sd</span> <span class="o">=</span> <span class="mh">0xffff8001f94cba18</span><span class="p">,</span> 
    <span class="n">kref</span> <span class="o">=</span> <span class="p">{</span>
      <span class="n">refcount</span> <span class="o">=</span> <span class="p">{</span>
        <span class="n">refs</span> <span class="o">=</span> <span class="p">{</span>
          <span class="n">counter</span> <span class="o">=</span> <span class="mh">0x1</span>
        <span class="p">}</span>
      <span class="p">}</span>
    <span class="p">},</span> 
    <span class="n">state_initialized</span> <span class="o">=</span> <span class="mh">0x1</span><span class="p">,</span> 
    <span class="n">state_in_sysfs</span> <span class="o">=</span> <span class="mh">0x1</span><span class="p">,</span> 
    <span class="n">state_add_uevent_sent</span> <span class="o">=</span> <span class="mh">0x1</span><span class="p">,</span> 
    <span class="n">state_remove_uevent_sent</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
    <span class="n">uevent_suppress</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
    <span class="n">kabi_reserved1</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
    <span class="n">kabi_reserved2</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
    <span class="n">kabi_reserved3</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
    <span class="n">kabi_reserved4</span> <span class="o">=</span> <span class="mh">0x0</span>
  <span class="p">},</span> 
  <span class="n">kobj_remove_work</span> <span class="o">=</span> <span class="p">{</span>
    <span class="n">data</span> <span class="o">=</span> <span class="p">{</span>
      <span class="n">counter</span> <span class="o">=</span> <span class="mh">0xfffffffe0</span>
    <span class="p">},</span> 
    <span class="n">entry</span> <span class="o">=</span> <span class="p">{</span>
      <span class="n">next</span> <span class="o">=</span> <span class="mh">0xffff8001f8e808d8</span><span class="p">,</span> 
      <span class="n">prev</span> <span class="o">=</span> <span class="mh">0xffff8001f8e808d8</span>
    <span class="p">},</span> 
    <span class="n">func</span> <span class="o">=</span> <span class="mh">0xffff00008033f4d8</span> <span class="o">&lt;</span><span class="n">sysfs_slab_remove_workfn</span><span class="o">&gt;</span><span class="p">,</span> 
    <span class="n">kabi_reserved1</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
    <span class="n">kabi_reserved2</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
    <span class="n">kabi_reserved3</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
    <span class="n">kabi_reserved4</span> <span class="o">=</span> <span class="mh">0x0</span>
  <span class="p">},</span> 
  <span class="n">memcg_params</span> <span class="o">=</span> <span class="p">{</span>
    <span class="n">root_cache</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
    <span class="p">{</span>
      <span class="p">{</span>
        <span class="n">memcg_caches</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
        <span class="n">__root_caches_node</span> <span class="o">=</span> <span class="p">{</span>
          <span class="n">next</span> <span class="o">=</span> <span class="mh">0xffff8000fee71320</span><span class="p">,</span> 
          <span class="n">prev</span> <span class="o">=</span> <span class="mh">0xffff000081308ba0</span> <span class="o">&lt;</span><span class="n">slab_root_caches</span><span class="o">&gt;</span>
        <span class="p">},</span> 
        <span class="n">children</span> <span class="o">=</span> <span class="p">{</span>
          <span class="n">next</span> <span class="o">=</span> <span class="mh">0xffff8001f8e80930</span><span class="p">,</span> 
          <span class="n">prev</span> <span class="o">=</span> <span class="mh">0xffff8001f8e80930</span>
        <span class="p">},</span> 
        <span class="n">dying</span> <span class="o">=</span> <span class="mh">0x0</span>
      <span class="p">},</span> 
      <span class="p">{</span>
        <span class="n">memcg</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
        <span class="n">children_node</span> <span class="o">=</span> <span class="p">{</span>
          <span class="n">next</span> <span class="o">=</span> <span class="mh">0xffff8000fee71320</span><span class="p">,</span> 
          <span class="n">prev</span> <span class="o">=</span> <span class="mh">0xffff000081308ba0</span> <span class="o">&lt;</span><span class="n">slab_root_caches</span><span class="o">&gt;</span>
        <span class="p">},</span> 
        <span class="n">kmem_caches_node</span> <span class="o">=</span> <span class="p">{</span>
          <span class="n">next</span> <span class="o">=</span> <span class="mh">0xffff8001f8e80930</span><span class="p">,</span> 
          <span class="n">prev</span> <span class="o">=</span> <span class="mh">0xffff8001f8e80930</span>
        <span class="p">},</span> 
        <span class="n">deact_fn</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
        <span class="p">{</span>
          <span class="n">deact_rcu_head</span> <span class="o">=</span> <span class="p">{</span>
            <span class="n">next</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
            <span class="n">func</span> <span class="o">=</span> <span class="mh">0x0</span>
          <span class="p">},</span> 
          <span class="n">deact_work</span> <span class="o">=</span> <span class="p">{</span>
            <span class="n">data</span> <span class="o">=</span> <span class="p">{</span>
              <span class="n">counter</span> <span class="o">=</span> <span class="mh">0x0</span>
            <span class="p">},</span> 
            <span class="n">entry</span> <span class="o">=</span> <span class="p">{</span>
              <span class="n">next</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
              <span class="n">prev</span> <span class="o">=</span> <span class="mh">0x0</span>
            <span class="p">},</span> 
            <span class="n">func</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
            <span class="n">kabi_reserved1</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
            <span class="n">kabi_reserved2</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
            <span class="n">kabi_reserved3</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
            <span class="n">kabi_reserved4</span> <span class="o">=</span> <span class="mh">0x0</span>
          <span class="p">}</span>
        <span class="p">}</span>
      <span class="p">}</span>
    <span class="p">}</span>
  <span class="p">},</span> 
  <span class="n">max_attr_size</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
  <span class="n">memcg_kset</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
  <span class="n">remote_node_defrag_ratio</span> <span class="o">=</span> <span class="mh">0x3e8</span><span class="p">,</span> 
  <span class="n">random_seq</span> <span class="o">=</span> <span class="mh">0xffff8001facd7800</span><span class="p">,</span> 
  <span class="n">useroffset</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
  <span class="n">usersize</span> <span class="o">=</span> <span class="mh">0x0</span><span class="p">,</span> 
  <span class="n">node</span> <span class="o">=</span> <span class="p">{</span><span class="mh">0xffff8000fbaab180</span><span class="p">,</span> <span class="mh">0xffff8001fb802580</span><span class="p">,</span> <span class="mh">0xffffffffffffffff</span><span class="p">,</span> <span class="mh">0xffffffffffffffff</span><span class="p">,</span> <span class="mh">0xffffffffffffffff</span><span class="p">,</span> <span class="mh">0xffffffffffffffff</span><span class="p">,</span> <span class="mh">0xffffffffffffffff</span><span class="p">,</span> <span class="mh">0xffffffffffffffff</span><span class="p">,</span> <span class="mh">0xffffffffffffffff</span><span class="p">,</span> <span class="mh">0xffffffffffffffff</span><span class="p">,</span> <span class="mh">0xffff000080f980a0</span><span class="p">,</span> <span class="mh">0x400c0000</span><span class="p">,</span> <span class="mh">0x5</span><span class="p">,</span> <span class="mh">0x8000000088</span><span class="p">,</span> <span class="mh">0x1e00000080</span><span class="p">,</span> <span class="mh">0x1e0000001e</span><span class="p">}</span>
<span class="p">}</span>
</pre></td></tr></tbody></table></code></div></div>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
</pre></td><td class="rouge-code"><pre><span class="nl">PS:</span>
<span class="err">每个物理页都对应一个</span><span class="k">struct</span> <span class="n">page</span><span class="err">结构体，结构体中有个联合体，其中定义了一些</span><span class="n">slab</span><span class="err">分配器要用到的成员。若</span>
<span class="err">该</span><span class="n">page</span><span class="err">用于</span><span class="n">slab</span><span class="err">，则下面成员将生效并被使用，代码如下。需要注意的是这里也有个</span><span class="n">freelist</span><span class="err">，它指向所属</span><span class="n">slab</span><span class="err">的</span>
<span class="err">第一个</span><span class="n">free</span> <span class="n">object</span><span class="p">,</span> <span class="err">不能和</span><span class="n">kmem_cache</span><span class="err">中</span><span class="n">freelist</span><span class="err">混淆。</span>
</pre></td></tr></tbody></table></code></div></div>

<h4 id="2-常用函数"><span class="me-2">2) 常用函数</span><a href="#2-常用函数" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h4>

<h5 id="1-kmem_cache_create"><span class="me-2">1 kmem_cache_create</span><a href="#1-kmem_cache_create" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h5>

<p>创建一个缓存管理描述符kmem_cache;</p>

<div class="language-xml highlighter-rouge"><div class="code-header">
        <span data-label-text="XML"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
</pre></td><td class="rouge-code"><pre>*name是一個字符串，存放kmem_cache緩存的名字；size是緩存所存放的對象的大小；align是slab內第一個對象
的偏移；flag是可選的配置項，用來控制緩存的行爲。最後一個參數ctor是對象的構造函數，一般是不需要的，以
NULL來代替。kmem_cache_create()成功執行之後會返回一個指向所創建的緩存的指針，否則返回NULL。
kmem_cache_create()可能會引起阻塞（睡眠），因此不能在中斷上下文中使用。
</pre></td></tr></tbody></table></code></div></div>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="n">crash</span><span class="o">&gt;</span> <span class="n">kmem</span> <span class="o">-</span><span class="n">s</span> <span class="n">slab_test_cachep</span>
<span class="n">CACHE</span>             <span class="n">OBJSIZE</span>  <span class="n">ALLOCATED</span>     <span class="n">TOTAL</span>  <span class="n">SLABS</span>  <span class="n">SSIZE</span>  <span class="n">NAME</span>
<span class="n">ffff8001fb843600</span>     <span class="mi">1600</span>          <span class="mi">0</span>         <span class="mi">0</span>      <span class="mi">0</span>    <span class="mi">32</span><span class="n">k</span>  <span class="n">slab_test_cachep</span>
</pre></td></tr></tbody></table></code></div></div>

<h5 id="2-kmem_cache_alloc申请object"><span class="me-2">2 kmem_cache_alloc申请object</span><a href="#2-kmem_cache_alloc申请object" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h5>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
</pre></td><td class="rouge-code"><pre><span class="c1">//1个slabs,申请8x4K, 1个slab有19个object， 目前被申请走2个， object的真实大小为1600bytes.</span>
<span class="n">crash</span><span class="o">&gt;</span> <span class="n">kmem</span> <span class="o">-</span><span class="n">s</span> <span class="n">slab_test_cachep</span>
<span class="n">CACHE</span>             <span class="n">OBJSIZE</span>  <span class="n">ALLOCATED</span>     <span class="n">TOTAL</span>  <span class="n">SLABS</span>  <span class="n">SSIZE</span>  <span class="n">NAME</span>
<span class="n">ffff8001f8e80800</span>     <span class="mi">1600</span>          <span class="mi">2</span>        <span class="mi">19</span>      <span class="mi">1</span>    <span class="mi">32</span><span class="n">k</span>  <span class="n">slab_test_cachep</span>
</pre></td></tr></tbody></table></code></div></div>

<p>object的分配通过kmem_cache_alloc()接口，实际分配object的过程会存在以下几种情形：</p>

<h6 id="1-fast-path">1&gt; fast path</h6>

<p>即可直接从本地cpu缓存中的freelist拿到可用object</p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
</pre></td><td class="rouge-code"><pre><span class="n">kmem_cache_alloc</span>
  <span class="n">slab_alloc</span>
    <span class="n">slab_alloc_node</span>
      <span class="o">--&gt;</span><span class="n">object</span> <span class="o">=</span> <span class="n">c</span><span class="o">-&gt;</span><span class="n">freelist</span>                                  <span class="c1">//本地cpu缓存的freelist有可用的object</span>
      <span class="o">--&gt;</span><span class="kt">void</span> <span class="o">*</span><span class="n">next_object</span><span class="o">=</span><span class="n">get_freepointer_safe</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">object</span><span class="p">);</span>    <span class="c1">//获取next object的地址，用于后面更新freelist</span>
      <span class="o">--&gt;</span><span class="n">this_cpu_cmpxchg_double</span>                               <span class="c1">//更新cpu_slab-&gt;freelist和cpu_slab-&gt;tid</span>
      <span class="o">--&gt;</span><span class="n">prefetch_freepointer</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">next_object</span><span class="p">);</span>                 <span class="c1">//优化语句，将next object的地址放入cacheline，提高后面用到时的命中率</span>
      <span class="o">--&gt;</span><span class="n">stat</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">ALLOC_FASTPATH</span><span class="p">);</span>                              <span class="c1">//设置状态为ALLOC_FASTPATH</span>
</pre></td></tr></tbody></table></code></div></div>

<h6 id="2-slow-path">2&gt; slow path</h6>

<p>本地cpu缓存中的freelist为NULL，但本地cpu缓存中的partial中有未满的slab</p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
</pre></td><td class="rouge-code"><pre><span class="n">kmem_cache_alloc</span>
  <span class="n">slab_alloc</span>
    <span class="n">slab_alloc_node</span>
      <span class="n">__slab_alloc</span>                                                                <span class="c1">//分配过程关闭了本地中断</span>
        <span class="n">___slab_alloc</span>
          <span class="o">--&gt;</span><span class="n">page</span> <span class="o">=</span> <span class="n">c</span><span class="o">-&gt;</span><span class="n">page</span><span class="err">为</span><span class="n">NULL</span><span class="err">的情况下</span>                 <span class="c1">//即本地cpu缓存中当前在使用的slab的free object已经分完</span>
          <span class="o">--&gt;</span><span class="k">goto</span> <span class="n">new_slab</span><span class="p">;</span>                             <span class="c1">//跳转到new_slab，从本地缓存池的partial取一个slab赋给page，并跳转到redo</span>
          <span class="o">--&gt;</span><span class="n">freelist</span> <span class="o">=</span> <span class="n">get_freelist</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">page</span><span class="p">)</span>           <span class="c1">//获取page中的freelist(注意：此freelist为strcut page中的，并非本地cpu缓存的freelist)</span>
          <span class="o">--&gt;</span><span class="n">c</span><span class="o">-&gt;</span><span class="n">freelist</span> <span class="o">=</span> <span class="n">get_freepointer</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">freelist</span><span class="p">)</span> <span class="c1">//将freelist重新赋给kmem_cache_cpu中的freelist     </span>
</pre></td></tr></tbody></table></code></div></div>

<h6 id="3-very-slow-path">3&gt; very slow path</h6>

<p>本地cpu缓存中的freelist为NULL，且本地cpu缓存中的partial也无slab可用。</p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="rouge-code"><pre><span class="n">kmem_cache_alloc</span>
  <span class="n">slab_alloc</span>
    <span class="n">slab_alloc_node</span>
      <span class="n">__slab_alloc</span>         <span class="c1">//分配过程关闭了本地中断</span>
        <span class="n">___slab_alloc</span>
          <span class="o">--&gt;</span><span class="n">page</span> <span class="o">=</span> <span class="n">c</span><span class="o">-&gt;</span><span class="n">page</span><span class="err">为</span><span class="n">NULL</span><span class="err">的情况下</span>  <span class="c1">//即本地cpu缓存中当前在使用的slab的free object已经分完                            </span>
          <span class="o">--&gt;</span><span class="k">goto</span> <span class="n">new_slab</span><span class="p">;</span>   <span class="c1">//跳转到new_slab，通过slub_percpu_partial(c)检查到本地cpu缓存池中partial无slab可用。</span>
          <span class="o">--&gt;</span><span class="n">freelist</span> <span class="o">=</span> <span class="n">new_slab_objects</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">gfpflags</span><span class="p">,</span> <span class="n">node</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">c</span><span class="p">);</span> <span class="c1">//此函数中会出现两种情况：情况 </span>
          <span class="c1">//1.当前node对应的kmem_cache_node中有可用partial slab，并从中获取slab分给本地cpu缓冲池。</span>
          <span class="c1">// 情况2.当前node对应的kmem_cache_node无可用的partial slab,过new_slab-&gt;allocate_slab-&gt;alloc_slab_page-&gt;alloc_pages从buddy分配器申请内存并创建新的 slab。两种情况最终都会返回一个可用的freelist</span>
          <span class="o">--&gt;</span><span class="n">c</span><span class="o">-&gt;</span><span class="n">freelist</span> <span class="o">=</span> <span class="n">get_freepointer</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">freelist</span><span class="p">)</span>  <span class="c1">//将freelist重新赋给kmem_cache_cpu中的freelist </span>
</pre></td></tr></tbody></table></code></div></div>

<h5 id="3-kmem_cache_free释放object"><span class="me-2">3 kmem_cache_free释放object</span><a href="#3-kmem_cache_free释放object" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h5>

<h5 id="4-kmem_cache_destory销毁kmem_cache"><span class="me-2">4 kmem_cache_destory销毁kmem_cache</span><a href="#4-kmem_cache_destory销毁kmem_cache" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h5>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="err">調用</span><span class="n">kmem_cache_destroy</span><span class="p">()</span><span class="err">之前應該滿足下面幾個條件：首先，</span><span class="n">cachep</span><span class="err">所指向的緩存中所有</span><span class="n">slab</span><span class="err">都爲空閒，否則</span>
<span class="err">的話是不可以撤銷的；其次在調用</span><span class="n">kmem_cache_destroy</span><span class="p">()</span><span class="err">過程中以及調用之後，調用者需要確保不會再訪問這個緩</span>
<span class="err">存；最後，該函數也可能會引起阻塞，因此不能在中斷上下文中使用。</span>
</pre></td></tr></tbody></table></code></div></div>

<h3 id="二slab_debugstrace"><span class="me-2">二、slab_debug/strace</span><a href="#二slab_debugstrace" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h3>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
</pre></td><td class="rouge-code"><pre><span class="nl">Reference:</span>
<span class="n">http</span><span class="o">:</span><span class="c1">//www.wowotech.net/memory_management/427.html SLUB DEBUG机制</span>
</pre></td></tr></tbody></table></code></div></div>

<h4 id="1-slab_debug机制"><span class="me-2">1 slab_debug机制</span><a href="#1-slab_debug机制" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h4>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="n">CONFIG_SLUB</span><span class="o">=</span><span class="n">y</span>
<span class="n">CONFIG_SLUB_DEBUG</span><span class="o">=</span><span class="n">y</span>
<span class="n">CONFIG_SLUB_DEBUG_ON</span><span class="o">=</span><span class="n">y</span>
</pre></td></tr></tbody></table></code></div></div>

<p>SLUB内存检测功能在某些情况下不能立刻检测出来，必须主动触发，因此我们需要借助slabinfo命令触发SLUB allocator检测功能.</p>

<p><a href="/posts/.\images\linux-slab\slab_debug-add-other-info.png" class="popup img-link "><img data-src="/posts/.\images\linux-slab\slab_debug-add-other-info.png" div="" align="left" style="zoom:80%" class="lazyload" data-proofer-ignore></a></p>

<p>CONFIG_SLUB_DEBUG_ON:</p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre><span class="n">kmem_cache</span><span class="err">的</span><span class="n">flag</span> <span class="o">=</span> <span class="n">SLAB_CONSISTENCY_CHECKS</span> <span class="o">|</span> <span class="n">SLAB_RED_ZONE</span><span class="o">|</span><span class="n">SLAB_POISON</span> <span class="o">|</span> <span class="n">SLAB_STORE_USER</span>
</pre></td></tr></tbody></table></code></div></div>

<p>SLUBU DEBUG关闭的情况下, free pointer是内嵌在object之中的, 但是SLUB DEBUG打开之后, free pointer是在object, 将FP后移就是因为为了检测use-after-free问题, 当free object时会在将object填充magic num(0x6b)。如果不后移的话，岂不是破坏了object之间的单链表关系。</p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
</pre></td><td class="rouge-code"><pre><span class="cp">#define SLUB_RED_INACTIVE   0xbb
#define SLUB_RED_ACTIVE     0xcc
</span><span class="cm">/* ...and for poisoning */</span>
<span class="cp">#define POISON_INUSE         0x5a    </span><span class="cm">/* for use-uninitialised poisoning */</span><span class="cp">
#define POISON_FREE          0x6b    </span><span class="cm">/* for use-after-free poisoning */</span><span class="cp">
#define POISON_END           0xa5    </span><span class="cm">/* end-byte of poisoning */</span><span class="cp">
</span></pre></td></tr></tbody></table></code></div></div>

<h4 id="2-slab-debug使用"><span class="me-2">2 slab debug使用</span><a href="#2-slab-debug使用" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h4>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="nl">Reference:</span>
<span class="n">http</span><span class="o">:</span><span class="c1">//linuxperf.com/?p=184 如何诊断SLUB问题</span>
<span class="n">https</span><span class="o">:</span><span class="c1">//blog.csdn.net/thwack/article/details/79865758  slab_trace</span>
</pre></td></tr></tbody></table></code></div></div>

<h5 id="1--slab-trace"><span class="me-2">1)  slab trace</span><a href="#1--slab-trace" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h5>

<h6 id="1观察slabinfo">1&gt;观察slabinfo</h6>

<p>启动后记录下slabinfo。运行一段时间，再观察slabinfo。找到增长比较大的slab。</p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre><span class="n">cat</span> <span class="o">/</span><span class="n">proc</span><span class="o">/</span><span class="n">slabinfo</span>
</pre></td></tr></tbody></table></code></div></div>

<h6 id="2打开slab-trace">2&gt;打开slab trace</h6>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="n">echo</span> <span class="mi">1</span> <span class="o">&gt;</span> <span class="o">/</span><span class="n">sys</span><span class="o">/</span><span class="n">kernel</span><span class="o">/</span><span class="n">slab</span><span class="o">/&lt;</span><span class="n">leaking_slab</span><span class="o">&gt;/</span><span class="n">trace</span>
<span class="n">sleep</span> <span class="mi">60</span>
<span class="n">echo</span> <span class="mi">0</span> <span class="o">&gt;</span> <span class="o">/</span><span class="n">sys</span><span class="o">/</span><span class="n">kernel</span><span class="o">/</span><span class="n">slab</span><span class="o">/&lt;</span><span class="n">leaking_slab</span><span class="o">&gt;/</span><span class="n">trace</span>
</pre></td></tr></tbody></table></code></div></div>

<h6 id="3---3-打开以后slab-trace会向console打印串口dmesg日志输出">3&gt;   3) 打开以后slab trace会向console打印。串口/dmesg日志输出</h6>

<p>如果console是串口的话很有可能把系统打的无响应。最好写一个脚本。运行一段时间后关闭slab</p>

<div class="language-c highlighter-rouge"><div class="code-header">
        <span data-label-text="C"><i class="fas fa-code fa-fw small"></i></span>
      <button aria-label="copy" data-title-succeed="Copied!"><i class="far fa-clipboard"></i></button></div><div class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="rouge-code"><pre><span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128477</span><span class="p">]</span> <span class="n">INFO</span><span class="o">:</span> <span class="n">Slab</span> <span class="mh">0x000000004afbdf16</span> <span class="n">objects</span><span class="o">=</span><span class="mi">19</span> <span class="n">used</span><span class="o">=</span><span class="mi">1</span> <span class="n">fp</span><span class="o">=</span><span class="mh">0x00000000e8006aea</span> <span class="n">flags</span><span class="o">=</span><span class="mh">0x7ffff0000008100</span>
<span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128483</span><span class="p">]</span> <span class="n">CPU</span><span class="o">:</span> <span class="mi">3</span> <span class="n">PID</span><span class="o">:</span> <span class="mi">31658</span> <span class="n">Comm</span><span class="o">:</span> <span class="n">rmmod</span> <span class="n">Tainted</span><span class="o">:</span> <span class="n">G</span>    <span class="n">B</span>      <span class="n">OE</span>     <span class="mi">4</span><span class="p">.</span><span class="mi">19</span><span class="p">.</span><span class="mi">90</span><span class="o">-</span><span class="n">vhulk2103</span><span class="p">.</span><span class="mi">1</span><span class="p">.</span><span class="mi">0</span><span class="p">.</span><span class="n">h469</span><span class="p">.</span><span class="n">eulerosv2r10</span><span class="p">.</span><span class="n">aarch64</span> <span class="err">#</span><span class="mi">1</span>
<span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128485</span><span class="p">]</span> <span class="n">Hardware</span> <span class="n">name</span><span class="o">:</span> <span class="n">QEMU</span> <span class="n">KVM</span> <span class="n">Virtual</span> <span class="n">Machine</span><span class="p">,</span> <span class="n">BIOS</span> <span class="mi">0</span><span class="p">.</span><span class="mi">0</span><span class="p">.</span><span class="mi">0</span> <span class="mo">02</span><span class="o">/</span><span class="mo">06</span><span class="o">/</span><span class="mi">2015</span>
<span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128487</span><span class="p">]</span> <span class="n">Call</span> <span class="n">trace</span><span class="o">:</span>
<span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128496</span><span class="p">]</span>  <span class="n">dump_backtrace</span><span class="o">+</span><span class="mh">0x0</span><span class="o">/</span><span class="mh">0x198</span>
<span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128499</span><span class="p">]</span>  <span class="n">show_stack</span><span class="o">+</span><span class="mh">0x24</span><span class="o">/</span><span class="mh">0x30</span>
<span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128504</span><span class="p">]</span>  <span class="n">dump_stack</span><span class="o">+</span><span class="mh">0xb0</span><span class="o">/</span><span class="mh">0x100</span>
<span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128510</span><span class="p">]</span>  <span class="n">slab_err</span><span class="o">+</span><span class="mh">0xc0</span><span class="o">/</span><span class="mh">0xe8</span>
<span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128513</span><span class="p">]</span>  <span class="n">__kmem_cache_shutdown</span><span class="o">+</span><span class="mh">0x1c0</span><span class="o">/</span><span class="mh">0x408</span>
<span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128517</span><span class="p">]</span>  <span class="n">shutdown_cache</span><span class="o">+</span><span class="mh">0x20</span><span class="o">/</span><span class="mh">0x1d8</span>
<span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128519</span><span class="p">]</span>  <span class="n">kmem_cache_destroy</span><span class="o">+</span><span class="mh">0x26c</span><span class="o">/</span><span class="mh">0x2e0</span>
<span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128527</span><span class="p">]</span>  <span class="n">kmem_cache_create_exit</span><span class="o">+</span><span class="mh">0x14</span><span class="o">/</span><span class="mh">0xfd8</span> <span class="p">[</span><span class="n">kmem_create</span><span class="p">]</span>
<span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128532</span><span class="p">]</span>  <span class="n">__arm64_sys_delete_module</span><span class="o">+</span><span class="mh">0x1a4</span><span class="o">/</span><span class="mh">0x2b8</span>
<span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128535</span><span class="p">]</span>  <span class="n">el0_svc_common</span><span class="o">+</span><span class="mh">0x80</span><span class="o">/</span><span class="mh">0x1c0</span>
<span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128538</span><span class="p">]</span>  <span class="n">el0_svc_handler</span><span class="o">+</span><span class="mh">0x78</span><span class="o">/</span><span class="mh">0xe0</span>
<span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128541</span><span class="p">]</span>  <span class="n">el0_svc</span><span class="o">+</span><span class="mh">0x10</span><span class="o">/</span><span class="mh">0x260</span>
<span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128546</span><span class="p">]</span> <span class="n">INFO</span><span class="o">:</span> <span class="n">Object</span> <span class="mh">0x0000000076a78344</span> <span class="err">@</span><span class="n">offset</span><span class="o">=</span><span class="mi">4992</span>
<span class="p">[</span> <span class="mi">2144</span><span class="p">.</span><span class="mi">128549</span><span class="p">]</span> <span class="n">kmem_cache_destroy</span> <span class="n">slab_test_cachep</span><span class="o">:</span> <span class="n">Slab</span> <span class="n">cache</span> <span class="n">still</span> <span class="n">has</span> <span class="n">objects</span>
</pre></td></tr></tbody></table></code></div></div>

<h5 id="2-slab-debug"><span class="me-2">2) slab debug</span><a href="#2-slab-debug" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h5>

<h5 id="3-slab-merge"><span class="me-2">3) slab merge</span><a href="#3-slab-merge" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h5>

<h3 id="三kmemleak"><span class="me-2">三、kmemleak</span><a href="#三kmemleak" class="anchor text-muted"><i class="fas fa-hashtag"></i></a></h3>

</div>

<div class="post-tail-wrapper text-muted">

  <!-- categories -->
  
  <div class="post-meta mb-3">
    <i class="far fa-folder-open fa-fw me-1"></i>
    
      <a href='/categories/linux/'>linux</a>,
      <a href='/categories/slab/'>Slab</a>
  </div>
  
  <!-- post.html -->

  <!-- tags -->
  
  <div class="post-tags">
    <i class="fa fa-tags fa-fw me-1"></i>
      
      <a href="/tags/slab/"
          class="post-tag no-text-decoration" >Slab</a>
      
  </div>
  
  
  <div class="post-tail-bottom
    d-flex justify-content-between align-items-center mt-3 pt-5 pb-2">
    <div class="license-wrapper">

      

        

        This post is licensed under 
        <a href="https://creativecommons.org/licenses/by/4.0/">
          CC BY 4.0
        </a>
         by the author.

      
    </div>

    <!-- Post sharing snippet -->

<div class="share-wrapper">
  <span class="share-label text-muted me-1">Share</span>
  <span class="share-icons">
    
    
    

    
      
      <a
        href="https://twitter.com/intent/tweet?text=linux%20Slab%20-%20Cheng%20Luo&url=https%3A%2F%2Fluochenglcs.github.io%2Fposts%2Flinux-slab%2F"
        data-bs-toggle="tooltip"
        data-bs-placement="top"
        title="Twitter"
        target="_blank"
        rel="noopener"
        aria-label="Twitter"
      >
        <i class="fa-fw fab fa-twitter"></i>
      </a>
    
      
      <a
        href="https://www.facebook.com/sharer/sharer.php?title=linux%20Slab%20-%20Cheng%20Luo&u=https%3A%2F%2Fluochenglcs.github.io%2Fposts%2Flinux-slab%2F"
        data-bs-toggle="tooltip"
        data-bs-placement="top"
        title="Facebook"
        target="_blank"
        rel="noopener"
        aria-label="Facebook"
      >
        <i class="fa-fw fab fa-facebook-square"></i>
      </a>
    
      
      <a
        href="https://t.me/share/url?url=https%3A%2F%2Fluochenglcs.github.io%2Fposts%2Flinux-slab%2F&text=linux%20Slab%20-%20Cheng%20Luo"
        data-bs-toggle="tooltip"
        data-bs-placement="top"
        title="Telegram"
        target="_blank"
        rel="noopener"
        aria-label="Telegram"
      >
        <i class="fa-fw fab fa-telegram"></i>
      </a>
    

    <i
      id="copy-link"
      class="fa-fw fas fa-link small"
      data-bs-toggle="tooltip"
      data-bs-placement="top"
      title="Copy link"
      data-title-succeed="Link copied successfully!"
    >
    </i>
  </span>
</div>


  </div><!-- .post-tail-bottom -->

</div><!-- div.post-tail-wrapper -->


      
    
      
    </div>
  </div>
  <!-- #core-wrapper -->

  <!-- panel -->
  <div id="panel-wrapper" class="col-xl-3 ps-2 text-muted">
    <div class="access">
      <!-- Get the last 5 posts from lastmod list. -->














  <div id="access-lastmod" class="post">
    <div class="panel-heading">Recently Updated</div>
    <ul class="post-content list-unstyled ps-0 pb-1 ms-1 mt-2">
      
        
        
        
        <li class="text-truncate lh-lg">
          <a href="/posts/%E5%86%85%E5%AD%98%E6%95%B0%E6%8D%AE%E5%BA%93/">MMDB (memory database)</a>
        </li>
      
        
        
        
        <li class="text-truncate lh-lg">
          <a href="/posts/userspace-rcu%E9%94%81/">userspace rcu lock</a>
        </li>
      
        
        
        
        <li class="text-truncate lh-lg">
          <a href="/posts/Real-time-operating-system/">Realtime Operating System</a>
        </li>
      
        
        
        
        <li class="text-truncate lh-lg">
          <a href="/posts/HUNDSUN-LightOS/">Hundsun Lightos</a>
        </li>
      
        
        
        
        <li class="text-truncate lh-lg">
          <a href="/posts/linux-struct-folio/">struct folio</a>
        </li>
      
    </ul>
  </div>
  <!-- #access-lastmod -->


      <!-- The trending tags list -->















  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
      
        
        

  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
      
        
        

  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
      
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        



  <div id="access-tags">
    <div class="panel-heading">Trending Tags</div>
    <div class="d-flex flex-wrap mt-3 mb-1 me-3">
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/lock/">lock</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/libumem/">libumem</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/mm/">mm</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/autonuma/">autonuma</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/bfs/">BFS</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/bus/">Bus</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/caladan/">caladan</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/damon/">damon</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/deep-learning/">Deep Learning</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/dma/">DMA</a>
      
    </div>
  </div>


    </div>

    
      
      



  <div id="toc-wrapper" class="ps-0 pe-4 mb-5">
    <div class="panel-heading ps-3 pt-2 mb-2">Contents</div>
    <nav id="toc"><ul><li>linux Slab<ul><li><a href="#一slab">一、slab</a><ul><li><a href="#1-主要数据结构">1) 主要数据结构</a><ul><li><a href="#1-struct-kmem_cache">1 struct kmem_cache</a></li></ul></li><li><a href="#2-常用函数">2) 常用函数</a><ul><li><a href="#1-kmem_cache_create">1 kmem_cache_create</a></li><li><a href="#2-kmem_cache_alloc申请object">2 kmem_cache_alloc申请object</a><ul><li><a href="#1-fast-path">1&gt; fast path</a></li><li><a href="#2-slow-path">2&gt; slow path</a></li><li><a href="#3-very-slow-path">3&gt; very slow path</a></li></ul></li><li><a href="#3-kmem_cache_free释放object">3 kmem_cache_free释放object</a></li><li><a href="#4-kmem_cache_destory销毁kmem_cache">4 kmem_cache_destory销毁kmem_cache</a></li></ul></li></ul></li><li><a href="#二slab_debugstrace">二、slab_debug/strace</a><ul><li><a href="#1-slab_debug机制">1 slab_debug机制</a></li><li><a href="#2-slab-debug使用">2 slab debug使用</a><ul><li><a href="#1--slab-trace">1)  slab trace</a><ul><li><a href="#1观察slabinfo">1&gt;观察slabinfo</a></li><li><a href="#2打开slab-trace">2&gt;打开slab trace</a></li><li><a href="#3---3-打开以后slab-trace会向console打印串口dmesg日志输出">3&gt;   3) 打开以后slab trace会向console打印。串口/dmesg日志输出</a></li></ul></li><li><a href="#2-slab-debug">2) slab debug</a></li><li><a href="#3-slab-merge">3) slab merge</a></li></ul></li></ul></li><li><a href="#三kmemleak">三、kmemleak</a></li></ul></li></ul></li></ul></nav>
  </div>
  


    
  </div>
</div>

<!-- tail -->

  <div class="row">
    <div id="tail-wrapper" class="col-12 col-lg-11 col-xl-9 px-3 pe-xl-4 mt-5">
      
        
        <!--
  Recommend the other 3 posts according to the tags and categories of the current post,
  if the number is not enough, use the other latest posts to supplement.
-->

<!-- The total size of related posts -->


<!-- An random integer that bigger than 0 -->


<!-- Equals to TAG_SCORE / {max_categories_hierarchy} -->








  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  
    
  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  

  






<!-- Fill with the other newlest posts -->





  <div id="related-posts" class="mb-2 mb-sm-4">
    <h3 class="pt-2 mb-4 ms-1" data-toc-skip>
      Further Reading
    </h3>
    <div class="row row-cols-1 row-cols-md-2 row-cols-xl-3 g-4 mb-4">
      
        
        
        <div class="col">
          <a href="/posts/linux-kcsan/" class="card post-preview h-100">
            <div class="card-body">
              <!--
  Date format snippet
  See: ${JS_ROOT}/utils/locale-dateime.js
-->





<em
  class="small"
  data-ts="1599782400"
  data-df="ll"
  
>
  Sep 11, 2020
</em>

              <h4 class="pt-0 my-2" data-toc-skip>The Kernel Concurrency Sanitizer (KCSAN)</h4>
              <div class="text-muted small">
                <p>
                  





                  1 kcasan

2 使用

                </p>
              </div>
            </div>
          </a>
        </div>
      
        
        
        <div class="col">
          <a href="/posts/linux-kprobe/" class="card post-preview h-100">
            <div class="card-body">
              <!--
  Date format snippet
  See: ${JS_ROOT}/utils/locale-dateime.js
-->





<em
  class="small"
  data-ts="1600041600"
  data-df="ll"
  
>
  Sep 14, 2020
</em>

              <h4 class="pt-0 my-2" data-toc-skip>Kernel Probe (kprobe)</h4>
              <div class="text-muted small">
                <p>
                  





                  1 kprobe

2 debugfs kprobe trace
kprobe trace 使用debugfs的trace功能
 p[:[GRP/]EVENT] [MOD:]SYM[+offs]|MEMADDR [FETCHARGS]  : Set a probe
 r[MAXACTIVE][:[GRP/]EVENT] [MOD:]SYM[+0] [FETCHARGS]  : Set a r...
                </p>
              </div>
            </div>
          </a>
        </div>
      
        
        
        <div class="col">
          <a href="/posts/linux-userfaultfd/" class="card post-preview h-100">
            <div class="card-body">
              <!--
  Date format snippet
  See: ${JS_ROOT}/utils/locale-dateime.js
-->





<em
  class="small"
  data-ts="1600905600"
  data-df="ll"
  
>
  Sep 24, 2020
</em>

              <h4 class="pt-0 my-2" data-toc-skip>Kernel userfaultfd</h4>
              <div class="text-muted small">
                <p>
                  





                  Userfault只支持匿名页，hugetlb、共享内存；

一、软件流程

1 初始化
调用__NR_userfaultfd syscall初始化
调用syscall初始化建立匿名inode文件，并初始化file-&amp;gt;private_data,并返回用户态文件fd。


  
    用户态：

    uffd = syscall(__NR_userfaultfd, O_CLOEXE...
                </p>
              </div>
            </div>
          </a>
        </div>
      
    </div>
    <!-- .card-deck -->
  </div>
  <!-- #related-posts -->


      
        
        <!-- Navigation buttons at the bottom of the post. -->

<div class="post-navigation d-flex justify-content-between">
  
    <a
      href="/posts/linux-kmsan/"
      class="btn btn-outline-primary"
      prompt="Older"
    >
      <p>The Kernel Memory Sanitizer (KMSAN)</p>
    </a>
  

  
    <a
      href="/posts/linux-vfio/"
      class="btn btn-outline-primary"
      prompt="Newer"
    >
      <p>Kernel Virtual Function I/O</p>
    </a>
  
</div>

      
        
        <!--  The comments switcher -->


      
    </div>
  </div>


        <!-- The Search results -->

<div id="search-result-wrapper" class="d-flex justify-content-center unloaded">
  <div class="col-11 post-content">
    <div id="search-hints">
      <!-- The trending tags list -->















  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
      
        
        

  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
      
        
        

  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
      
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        

  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
    
  
    
    
    
    
      
        
        



  <div id="access-tags">
    <div class="panel-heading">Trending Tags</div>
    <div class="d-flex flex-wrap mt-3 mb-1 me-3">
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/lock/">lock</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/libumem/">libumem</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/mm/">mm</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/autonuma/">autonuma</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/bfs/">BFS</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/bus/">Bus</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/caladan/">caladan</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/damon/">damon</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/deep-learning/">Deep Learning</a>
      
        
        <a class="post-tag btn btn-outline-primary" href="/tags/dma/">DMA</a>
      
    </div>
  </div>


    </div>
    <div id="search-results" class="d-flex flex-wrap justify-content-center text-muted mt-3"></div>
  </div>
</div>

      </div>
    </div>

    <!-- The Footer -->

<footer>
  <div class="container px-lg-4">
    <div class="d-flex justify-content-center align-items-center text-muted mx-md-3">
      <p>Using the <a href="https://jekyllrb.com" target="_blank" rel="noopener">Jekyll</a> theme <a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank" rel="noopener">Chirpy</a>
      </p>

      <p>©
        2023
        <a href="https://gitee.com/luochenglcs">luochunsheng</a>.
        
          <span
            data-bs-toggle="tooltip"
            data-bs-placement="top"
            title="Except where otherwise noted, the blog posts on this site are licensed under the Creative Commons Attribution 4.0 International (CC BY 4.0) License by the author."
          >Some rights reserved.</span>
        
      </p>
    </div>
  </div>
</footer>


    <div id="mask"></div>

    <button id="back-to-top" aria-label="back-to-top" class="btn btn-lg btn-box-shadow">
      <i class="fas fa-angle-up"></i>
    </button>

    
      <div
        id="notification"
        class="toast"
        role="alert"
        aria-live="assertive"
        aria-atomic="true"
        data-bs-animation="true"
        data-bs-autohide="false"
      >
        <div class="toast-header">
          <button
            type="button"
            class="btn-close ms-auto"
            data-bs-dismiss="toast"
            aria-label="Close"
          ></button>
        </div>
        <div class="toast-body text-center pt-0">
          <p class="px-2 mb-3">A new version of content is available.</p>
          <button type="button" class="btn btn-primary" aria-label="Update">
            Update
          </button>
        </div>
      </div>
    

    <!-- JS selector for site. -->

<!-- commons -->



<!-- layout specified -->


  

  
    <!-- image lazy-loading & popup & clipboard -->
    
  















  
    

    

  

  
    

    

  

  
    

    

  

  
    

    

  

  
    

    

  

  
    

    

  

  
    

    

  

  
    

    

  

  
    

    

  

  
    

    

  

  
    

    

  



  <script src="https://cdn.jsdelivr.net/combine/npm/jquery@3.7.0/dist/jquery.min.js,npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js,npm/simple-jekyll-search@1.10.0/dest/simple-jekyll-search.min.js,npm/lazysizes@5.3.2/lazysizes.min.js,npm/magnific-popup@1.1.0/dist/jquery.magnific-popup.min.js,npm/clipboard@2.0.11/dist/clipboard.min.js,npm/dayjs@1.11.7/dayjs.min.js,npm/dayjs@1.11.7/locale/en.min.js,npm/dayjs@1.11.7/plugin/relativeTime.min.js,npm/dayjs@1.11.7/plugin/localizedFormat.min.js,npm/tocbot@4.21.0/dist/tocbot.min.js"></script>






<script defer src="/assets/js/dist/post.min.js"></script>






    

    <!--
  Jekyll Simple Search loader
  See: <https://github.com/christian-fei/Simple-Jekyll-Search>
-->





<script>
  /* Note: dependent library will be loaded in `js-selector.html` */
  SimpleJekyllSearch({
    searchInput: document.getElementById('search-input'),
    resultsContainer: document.getElementById('search-results'),
    json: '/assets/js/data/search.json',
    searchResultTemplate: '<div class="px-1 px-sm-2 px-lg-4 px-xl-0">  <a href="{url}">{title}</a>  <div class="post-meta d-flex flex-column flex-sm-row text-muted mt-1 mb-1">    {categories}    {tags}  </div>  <p>{snippet}</p></div>',
    noResultsText: '<p class="mt-5"></p>',
    templateMiddleware: function(prop, value, template) {
      if (prop === 'categories') {
        if (value === '') {
          return `${value}`;
        } else {
          return `<div class="me-sm-4"><i class="far fa-folder fa-fw"></i>${value}</div>`;
        }
      }

      if (prop === 'tags') {
        if (value === '') {
          return `${value}`;
        } else {
          return `<div><i class="fa fa-tag fa-fw"></i>${value}</div>`;
        }
      }
    }
  });
</script>

  </body>
</html>

